package com.demo.druid.filter;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.proxy.jdbc.JdbcParameter;
import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
import com.alibaba.druid.proxy.jdbc.StatementProxy;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;

/**
 * SQL执行日志记录
 */
public class LogSlowSqlFilter extends StatFilter {
	private final static Log LOG = LogFactory.getLog(LogSlowSqlFilter.class);

	private final void internalAfterStatementExecute(StatementProxy statement) {
		final long nowNano = System.nanoTime();
		final long nanos = nowNano - statement.getLastExecuteStartNano();

		if (statement.getSqlStat() != null) {
			long millis = nanos / (1000 * 1000);
			if (millis >= slowSqlMillis) {
				int parametersSize = statement.getParametersSize();
				List<Object> parameters = new ArrayList<Object>(parametersSize);
				for (int i = 0; i < parametersSize; ++i) {
					JdbcParameter parameter = statement.getParameter(i);
					parameters.add(parameter.getValue());
				}

				if (logSlowSql) {
					String formattedSql = SQLUtils.format(statement.getLastExecuteSql(), getDbType(), parameters);
					LOG.error("slow sql " + millis + " millis. \n" + formattedSql + "\n");
				}
			}
		}
	}

	@Override
	protected void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) {
		internalAfterStatementExecute(statement);
	}

	@Override
	protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) {
		internalAfterStatementExecute(statement);
	}

	@Override
	protected void statementExecuteAfter(StatementProxy statement, String sql, boolean firstResult) {
		internalAfterStatementExecute(statement);
	}

	@Override
	protected void statementExecuteBatchAfter(StatementProxy statement, int[] result) {
		internalAfterStatementExecute(statement);
	}

	@Override
	protected void statementExecuteUpdateBefore(StatementProxy statement, String sql) {}

	@Override
	protected void statementExecuteQueryBefore(StatementProxy statement, String sql) {}

	@Override
	protected void statementExecuteBefore(StatementProxy statement, String sql) {}

	@Override
	protected void statementExecuteBatchBefore(StatementProxy statement) {}

	@Override
	protected void statement_executeErrorAfter(StatementProxy statement, String sql, Throwable error) {}

	@Override
	protected void resultSetOpenAfter(ResultSetProxy resultSet) {}

}
